package my.threading;

import java.util.Date;
import java.util.Random;
import java.util.concurrent.*;

public class FutureExample
{
	LinkedBlockingQueue<FutureTask<Double>> queue = new LinkedBlockingQueue<FutureTask<Double>>();
	
	public static void main(String [] args) throws InterruptedException, ExecutionException
	{		
		FutureExample t = new FutureExample();
		t.run();
	}
	
	boolean stillLoading = true;
	public void run() throws InterruptedException, ExecutionException
	{
		Thread t = new Thread(new Producer());
		t.start();
		while (!queue.isEmpty() || stillLoading)
		{
			if(queue.peek() != null && queue.peek().isDone())
			{
				System.out.println("Value: " + queue.poll().get());
			}
		}
		System.out.println("Done Processing");
		System.exit(0);
	}
	
	class Producer implements Runnable
	{
		public void run()
		{
			Executor ex = Executors.newCachedThreadPool();
			
			for (int i =0; i < 1000; i++)
			{
				FutureTask<Double> task = new FutureTask<Double>(new Calculate());
				queue.add(task);
				ex.execute(task);
			}
			stillLoading = false;
		}
	}
	
	class Calculate implements Callable
	{

		public Object call() throws Exception
		{			
			Random r = new Random((new Date()).getTime());
			if((r.nextInt() % 2) == 0)
			{
				return 1.7 * r.nextInt();
			}
			
			double tally = r.nextDouble();
			for (int i = 0; i < 1000; i++)
			{
				tally *= (r.nextDouble() + 1);
			}
			
			return tally;
		}
	}
}
